package cn.chiship.bs.api.biz.service.impl;


import cn.chiship.bs.api.core.config.properties.GlobalProperties;
import cn.chiship.sdk.core.base.constants.CacheConstants;
import cn.chiship.sdk.core.enums.BaseResultEnum;
import cn.chiship.sdk.core.exception.custom.AccessTokenException;
import cn.chiship.sdk.core.exception.custom.BusinessException;
import cn.chiship.sdk.core.util.StringUtil;
import cn.chiship.bs.api.biz.pojo.vo.CacheUserVO;
import cn.chiship.bs.api.biz.service.RedisService;
import cn.chiship.bs.api.biz.service.UserCacheService;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

/**
 * @author LiJian
 */
@Service
public class UserCacheServiceImpl implements UserCacheService {
    /**
     * 保存7天
     */
    public static final Long USER_TOKEN_EXPIRE_TIME = 604800L;
    public static final String CACHE_COMMON_NAME = "AUTH";

    @Autowired
    private RedisService redisService;
    @Autowired
    private GlobalProperties globalProperties;

    @Override
    public String getToken() {
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        if (requestAttributes == null) {
            throw new BusinessException("getRequestAttributes为空!");
        }
        HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
        return request.getHeader("Access-Token");
    }

    @Override
    public CacheUserVO getUser() {
        return this.getUserByToken(this.getToken());
    }

    @Override
    public boolean cacheUser(CacheUserVO user) {
        return this.cacheUser(formatToken(this.getToken()), user);
    }

    @Override
    public boolean cacheUser(String token, CacheUserVO user) {
        return this.redisService.set(formatToken(token), JSONObject.parseObject(JSON.toJSONString(user)), USER_TOKEN_EXPIRE_TIME);
    }

    @Override
    public CacheUserVO getUserByToken(String token) {
        Object obj = this.redisService.get(formatToken(token));
        if (StringUtil.isNull(obj)) {
            throw new AccessTokenException(BaseResultEnum.ERROR_TOKEN);
        }
        return JSON.toJavaObject((JSONObject) obj, CacheUserVO.class);
    }

    @Override
    public boolean removeUser() {
        return this.removeUserByToken(this.getToken());
    }

    @Override
    public boolean removeUserByToken(String token) {
        this.redisService.del(formatToken(token));
        return true;
    }

    @Override
    public boolean isValid() {
        return this.isValid(this.getToken());
    }

    @Override
    public boolean isValid(String token) {
        return this.redisService.hasKey(formatToken(token));
    }

    @Override
    public void removeUserAll() {
        this.redisService.removeAll(CACHE_COMMON_NAME + ":API_AUTHORIZATION:" + globalProperties.getName() + ":");
    }

    private String formatToken(String token) {
        return (CACHE_COMMON_NAME + ":API_AUTHORIZATION:" + globalProperties.getName() + ":").concat(CacheConstants.REDIS_TOKEN_PREFIX.concat(token));
    }
}
